package com.budwk.app.sqfw.services.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.sqfw.constants.ThirdCompanyUrlConstants;
import com.budwk.app.sqfw.dto.ThreeGuaranteeQueryDTO;
import com.budwk.app.sqfw.dto.ThreeGuaranteeControllerDTO;
import com.budwk.app.sqfw.dto.ThreeGuaranteeDTO;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfw.services.ThreeGuaranteeService;
import com.budwk.app.sqfw.vo.ThreeGuaranteeVO;
import com.budwk.app.sqfwV2.dto.entity.SqfwShopsBaseInfo;
import com.budwk.app.sqfwV2.service.ShopsBaseInfoService;
import com.budwk.app.sys.models.Sys_user;
import com.budwk.app.sys.services.SysUserService;
import com.budwk.starter.common.page.Pagination;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.nutz.dao.Cnd;
import org.nutz.dao.util.cri.SqlExpressionGroup;
import org.nutz.dao.util.cri.Static;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * @author ZY.Wang
 * @since 2024/4/23
 */
@IocBean
@Slf4j
public class ThreeGuaranteeServiceImpl implements ThreeGuaranteeService {

    @Inject
    private SqfwFormsummaryNewService sqfwFormSummaryService;
    @Inject
    private SysUserService sysUserService;
    @Inject
    private ShopsBaseInfoService shopsBaseInfoService;


    /**
     * 插入三包信息
     *
     * @param userId        用户id
     * @param controllerDTO 三包信息
     */
    @Override
    public void insertThreeGuarantee(String userId, ThreeGuaranteeControllerDTO controllerDTO) {
        Sys_user sysUser = sysUserService.fetch(userId);

        // 第一步插入formSummary
        Sqfw_formSummary_new formSummary = new Sqfw_formSummary_new();
        Sqfw_formSummary_new baseFormSummary = controllerDTO.getBaseFormSummary();
        BeanUtil.copyProperties(baseFormSummary, formSummary);
        formSummary.setFillDate(new Date());
        formSummary.setCreateBy(userId);
        formSummary.setCreateDate(new Date());
        formSummary.setUpdateBy(userId);
        formSummary.setUpdateDate(new Date());
        formSummary.setProvince(sysUser.getProvince());
        formSummary.setCity(sysUser.getCity());
        formSummary.setDistrict(sysUser.getDistrict());
        formSummary.setCounty(sysUser.getCounty());
        formSummary.setCommunity(sysUser.getCommunity());
        formSummary.setType("门前三包");
        String paramDataStr = formSummary.getParamData();

        ThreeGuaranteeDTO threeGuaranteeDTO = JSONObject.parseObject(paramDataStr, ThreeGuaranteeDTO.class);

        formSummary.setLongitude(threeGuaranteeDTO.getLongitude());
        formSummary.setLatitude(threeGuaranteeDTO.getLatitude());
        sqfwFormSummaryService.insert(formSummary);

        // 插入门店信息
        try {
            saveShopInfo(sysUser, threeGuaranteeDTO);
        } catch (Exception e) {
            log.info("门前三包店铺信息保存重复!");
        }

        // 第二步调用其他公司接口保存数据
        // wzy 2024-6-20 暂时取消调用第三方数据
        // submitToThirdCompany(threeGuaranteeDTO, baseFormSummary, sysUser);
    }

    private void saveShopInfo(Sys_user sysUser, ThreeGuaranteeDTO threeGuarantee) {
        SqfwShopsBaseInfo sqfwShopsBaseInfo = new SqfwShopsBaseInfo();
        sqfwShopsBaseInfo.setType(SupportBusinessTypeEnum.THREE_GUARANTEE.getCode());
        sqfwShopsBaseInfo.setPlaceName(threeGuarantee.getPlaceName());
        sqfwShopsBaseInfo.setBusinessLicenseName(threeGuarantee.getBusinessLicenseName());
        sqfwShopsBaseInfo.setSocialCreditCode(threeGuarantee.getSocialCreditCode());
        sqfwShopsBaseInfo.setAddress(threeGuarantee.getAddress());
        sqfwShopsBaseInfo.setDetailAddress(sysUser.getProvince() + sysUser.getCity() + sysUser.getDistrict() + sysUser.getCounty() + sysUser.getCommunity() + threeGuarantee.getAddress());
        sqfwShopsBaseInfo.setActualAddress(threeGuarantee.getAddress());
        sqfwShopsBaseInfo.setOperator(threeGuarantee.getOperator());
        sqfwShopsBaseInfo.setOperatorTelephone(threeGuarantee.getOperatorPhone());
        sqfwShopsBaseInfo.setPlaceArea(threeGuarantee.getPlaceArea());
        sqfwShopsBaseInfo.setProvince(sysUser.getProvince());
        sqfwShopsBaseInfo.setCity(sysUser.getCity());
        sqfwShopsBaseInfo.setDistrict(sysUser.getDistrict());
        sqfwShopsBaseInfo.setCounty(sysUser.getCounty());
        sqfwShopsBaseInfo.setCommunity(sysUser.getCommunity());
        sqfwShopsBaseInfo.setCreateDate(LocalDateTime.now());
        sqfwShopsBaseInfo.setCreateId(sysUser.getId());
        sqfwShopsBaseInfo.setUpdateDate(LocalDateTime.now());
        sqfwShopsBaseInfo.setDeleted(false);
        sqfwShopsBaseInfo.setServiceType(SupportBusinessTypeEnum.THREE_GUARANTEE.getCode());
        sqfwShopsBaseInfo.setLongitude(threeGuarantee.getLongitude());
        sqfwShopsBaseInfo.setLatitude(threeGuarantee.getLatitude());
        shopsBaseInfoService.saveShopInfo(sqfwShopsBaseInfo);
    }

    /**
     * 根据第三方门店id查询门店信息
     *
     * @param storeId 门店id
     * @return 结果
     */
    @Override
    public ThreeGuaranteeDTO getStoreByStoreId(String storeId) {
        ThreeGuaranteeDTO resultVO = new ThreeGuaranteeDTO();
        // 首先从我们的数据库中进行查询，如果含有最好不过
        Cnd cnd = Cnd.NEW();
        cnd.and(new Static(" param_data->>'thirdStoreId' = '" + storeId + "' "));
        cnd.desc(Sqfw_formSummary_new::getFillDate);
        cnd.limit(1, 1);
        List<Sqfw_formSummary_new> queryList = sqfwFormSummaryService.query(cnd);
        if (CollectionUtil.isNotEmpty(queryList)) {
            Sqfw_formSummary_new assistanceFormSummary = queryList.get(0);
            String paramData = assistanceFormSummary.getParamData();
            if (StringUtils.isBlank(paramData)) return resultVO;

            try {
                return JSONObject.parseObject(paramData, ThreeGuaranteeDTO.class);
            } catch (Exception e) {
                return resultVO;
            }
        } else {
            Map<String, Object> thirdParamMap = Maps.newHashMap();
            thirdParamMap.put("id", storeId);
            String resStr = HttpUtil.get(ThirdCompanyUrlConstants.threeGuaranteeQueryById, thirdParamMap);
            if (StringUtils.isBlank(resStr)) return resultVO;

            JSONObject responseJson = JSONObject.parseObject(resStr);
            Integer code = responseJson.getInteger("code");
            if (code == 200) {
                JSONObject resultJson = responseJson.getJSONObject("result");

                resultVO.setThirdStoreId(resultJson.getString("id"));
                resultVO.setPlaceName(resultJson.getString("theShopName"));
                resultVO.setBusinessLicenseName(resultJson.getString("store"));
                resultVO.setSocialCreditCode(resultJson.getString("unifiedSocialCreditCode"));
                resultVO.setLocation(resultJson.getString("location"));
                resultVO.setLatitude(resultJson.getString("latitude"));
                resultVO.setLongitude(resultJson.getString("longitude"));
                resultVO.setAddress(resultJson.getString("address"));
                resultVO.setPlaceArea(resultJson.getString("storeArea"));
                resultVO.setOperator(resultJson.getString("legalPerson"));

                Integer isKitchenUnit = resultJson.getInteger("isKitchenUnit");
                resultVO.setIsKitchenMerchant(isKitchenUnit == 1 ? "是" : "否");

                resultVO.setKitchenCompany(resultJson.getString("kitchenCompany"));
                resultVO.setOperatorPhone(resultJson.getString("legalPhone"));
            }

            return resultVO;
        }
    }

    @Override
    public Pagination pageListThreeGuarantee(ThreeGuaranteeQueryDTO queryDTO) {
        Integer pageNo = Optional.ofNullable(queryDTO.getPageNo()).orElse(1);
        Integer pageSize = Optional.ofNullable(queryDTO.getPageSize()).orElse(10);
        Cnd cnd = Cnd.NEW();
        cnd.and(Sqfw_formSummary_new::getType, "=", "门前三包");

        if (StringUtils.isNotBlank(queryDTO.getQueryCondition())) {
            SqlExpressionGroup placeName = Cnd.exps(new Static(" param_data->>'placeName' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup businessLicenseName = Cnd.exps(new Static(" param_data->>'businessLicenseName' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup socialCreditCode = Cnd.exps(new Static(" param_data->>'socialCreditCode' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup location = Cnd.exps(new Static(" param_data->>'location' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup address = Cnd.exps(new Static(" param_data->>'address' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup operator = Cnd.exps(new Static(" param_data->>'operator' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup operatorPhone = Cnd.exps(new Static(" param_data->>'operatorPhone' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup placeArea = Cnd.exps(new Static(" param_data->>'placeArea' like '%" + queryDTO.getQueryCondition() + "%'"));
            SqlExpressionGroup kitchenCompany = Cnd.exps(new Static(" param_data->>'kitchenCompany' like '%" + queryDTO.getQueryCondition() + "%'"));
            cnd.and(placeName.or(businessLicenseName).or(socialCreditCode).or(location).or(address).or(operator).or(operatorPhone).or(placeArea).or(kitchenCompany));
        }

        Pagination pagination = sqfwFormSummaryService.listPage(pageNo, pageSize, cnd);

        List<ThreeGuaranteeVO> resultList = Lists.newArrayList();
        List<Sqfw_formSummary_new> list = pagination.getList(Sqfw_formSummary_new.class);
        for (Sqfw_formSummary_new formSummary : list) {
            ThreeGuaranteeVO vo = new ThreeGuaranteeVO();
            BeanUtil.copyProperties(formSummary, vo);

            String paramData = formSummary.getParamData();
            ThreeGuaranteeDTO threeGuaranteeDTO = JSONObject.parseObject(paramData, ThreeGuaranteeDTO.class);
            BeanUtil.copyProperties(threeGuaranteeDTO, vo);
            resultList.add(vo);
        }

        pagination.setList(resultList);
        return pagination;
    }

    @Override
    public void deleteAssistanceFormSummary(String id) {
        sqfwFormSummaryService.delete(id);
    }

    /**
     * 提交数据到第三方公司
     *
     * @param threeGuaranteeDTO 三包数据
     * @param baseFormSummary   基础表单
     * @param sysUser           用户
     */
    private void submitToThirdCompany(ThreeGuaranteeDTO threeGuaranteeDTO, Sqfw_formSummary_new baseFormSummary, Sys_user sysUser) {
        if (StringUtils.isBlank(threeGuaranteeDTO.getThirdStoreId())) return;
        Map<String, Object> threeGuaranteeThirdParamMap = Maps.newHashMap();
        threeGuaranteeThirdParamMap.put("id", threeGuaranteeDTO.getThirdStoreId());
        threeGuaranteeThirdParamMap.put("store", threeGuaranteeDTO.getPlaceName());
        threeGuaranteeThirdParamMap.put("unifiedSocialCreditCode", threeGuaranteeDTO.getSocialCreditCode());
        threeGuaranteeThirdParamMap.put("latitude", threeGuaranteeDTO.getLatitude());
        threeGuaranteeThirdParamMap.put("longitude", threeGuaranteeDTO.getLongitude());
        threeGuaranteeThirdParamMap.put("address", threeGuaranteeDTO.getAddress());
        threeGuaranteeThirdParamMap.put("storeArea", threeGuaranteeDTO.getPlaceArea());
        threeGuaranteeThirdParamMap.put("owner", threeGuaranteeDTO.getOperator());
        threeGuaranteeThirdParamMap.put("legalPerson", threeGuaranteeDTO.getOperator());

        String isKitchenMerchant = threeGuaranteeDTO.getIsKitchenMerchant();
        String isKitchenMerchantStr = isKitchenMerchant.equals("是") ? "1" : "2";
        threeGuaranteeThirdParamMap.put("isKitchenUnit", isKitchenMerchantStr);

        threeGuaranteeThirdParamMap.put("kitchenCompany", threeGuaranteeDTO.getKitchenCompany());
        threeGuaranteeThirdParamMap.put("legalPhone", threeGuaranteeDTO.getOperatorPhone());
        threeGuaranteeThirdParamMap.put("ownerPhone", threeGuaranteeDTO.getOperatorPhone());
        threeGuaranteeThirdParamMap.put("roadBelong", baseFormSummary.getDistrict());
        threeGuaranteeThirdParamMap.put("departName", sysUser.getUnitName());
        threeGuaranteeThirdParamMap.put("theShopName", threeGuaranteeDTO.getBusinessLicenseName());
        threeGuaranteeThirdParamMap.put("manageUnit", "贵阳市综合行政执法局");
        threeGuaranteeThirdParamMap.put("inspectorTime", new Date());
        threeGuaranteeThirdParamMap.put("appealStatus", "0");
        threeGuaranteeThirdParamMap.put("unit", "520181400010002");

        threeGuaranteeThirdParamMap.put("draftState", 1);

        String resStr = "{}";

        OkHttpClient client = new OkHttpClient().newBuilder() //
                .readTimeout(60, TimeUnit.SECONDS) // 设置读取超时时间
                .writeTimeout(60, TimeUnit.SECONDS) // 设置写的超时时间
                .connectTimeout(60, TimeUnit.SECONDS) // 设置连接超时时间
                .build();

        MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        RequestBody body = RequestBody.create(JSONObject.toJSONString(threeGuaranteeThirdParamMap), JSON);
        Request request = new Request.Builder().url(ThirdCompanyUrlConstants.threeGuaranteeEditDraft).put(body).build();
        try (Response response = client.newCall(request).execute()) {
            ResponseBody responseBody = response.body();
            resStr = responseBody.string();
            log.info("three guarantee third url res:{}", resStr);
            JSONObject resJsonObj = JSONObject.parseObject(resStr);
            Integer status = resJsonObj.getInteger("code");
            if (status != 200) {
                log.warn("third part url error,{}", resJsonObj.getString("message"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
